/**
 * Copyright(c) kyle.
 */
package org.example.metrics;

import com.codahale.metrics.ConsoleReporter;
import com.codahale.metrics.DerivativeGauge;
import com.codahale.metrics.Gauge;
import com.codahale.metrics.MetricRegistry;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.CacheStats;
import com.google.common.cache.LoadingCache;

import java.util.concurrent.TimeUnit;

import static java.util.concurrent.ThreadLocalRandom.current;

/**
 * 允许从某个Gauge value中获取特定的属性和值，
 * 比如，我们将Cache的Stats作为一个Metric，
 * Stats中包含非常多的属性，我们可以通过Derivative Gauge只取其中一两个属性
 *
 * @author kyle
 * @version 1.00.00
 * @updateUser [Kyle]
 * @updateRemark [说明本次修改内容]
 * @date [2021-09-21 12:51]
 * @since [2021-09-21 12:51]
 */
public class DerivativeGaugeExample {
    public static final LoadingCache<String, String> cache =
            CacheBuilder.newBuilder().maximumSize(10).expireAfterAccess(5, TimeUnit.SECONDS)
                    .recordStats().build(new CacheLoader<String, String>() {
                @Override
                public String load(String s) throws Exception {
                    return s.toUpperCase();
                }
            });
    public static final MetricRegistry registry = new MetricRegistry();

    public static final ConsoleReporter reporter = ConsoleReporter.forRegistry(registry)
            .convertRatesTo(TimeUnit.SECONDS)
            .convertDurationsTo(TimeUnit.SECONDS)
            .build();

    public static void main(String[] args) throws InterruptedException {
        reporter.start(10, TimeUnit.SECONDS);
        Gauge<CacheStats> cacheGauge = registry.gauge("cached-stats",
                () -> cache::stats);
        registry.register("missCount", new DerivativeGauge<CacheStats, Long>(cacheGauge) {
            @Override
            protected Long transform(CacheStats cacheStats) {
                return cacheStats.missCount();
            }
        });
        registry.register("loadExceptionCount", new DerivativeGauge<CacheStats,Long>(cacheGauge) {
            @Override
            protected Long transform(CacheStats cacheStats) {
                return cacheStats.loadExceptionCount();
            }
        });
        while (true){
            business();
            randomSleep();
        }
    }

    private static void business() {
       cache.getUnchecked("alex");
    }

    private static void randomSleep() {
        try {
            TimeUnit.SECONDS.sleep(current().nextInt(6));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
